/***************************************************
 ** @Desc : This file for 对接代付
 ** @Time : 2019.04.22 13:38 
 ** @Author : Joker
 ** @File : api_pay
 ** @Last Modified by : Joker
 ** @Last Modified time: 2019.04.22 13:38
 ** @Software: GoLand
****************************************************/
package controllers

import (
	"encoding/json"
	"github.com/astaxie/beego"
	"recharge/models"
	"recharge/sys"
	"recharge/utils"
	"recharge/utils/interface_config"
	"strconv"
	"strings"
)

type ApiPay struct {
	beego.Controller
}

// 对接代付
// @router /api/pay/?:params [post]
func (the *ApiPay) ApiRecharge() {
	params := models.ApiPayRequestParams{}
	params.MerchantNo = the.GetString("MerchantNo")
	params.OrderPrice = the.GetString("OrderPrice")
	params.OutOrderNo = the.GetString("OutOrderNo")
	params.TradeTime = the.GetString("TradeTime")
	params.UserType = the.GetString("UserType")
	params.AccountNo = the.GetString("AccountNo")
	params.AccountName = the.GetString("AccountName")
	params.BankNo = the.GetString("BankNo")
	params.Issuer = the.GetString("Issuer")
	params.ApiNotifyUrl = the.GetString("ApiNotifyUrl")
	params.Item = the.GetString("Item")
	params.Sign = the.GetString("Sign")

	//获取客户端ip
	ip := the.Ctx.Input.IP()
	// 校验参数签名
	check, out := apiRPImpl.CheckPayRequestParams(params, ip)
	if check {

		XFMerchant := merchantFactor.QueryOneMerchantForPay(params.OrderPrice)
		if XFMerchant.MerchantNo == "" || XFMerchant.Id == 0 {
			out["resultCode"] = "9999"
			out["msg"] = "请联系管理员更新代付通道"
		} else {

			record := models.WithdrawRecord{}
			userId, _ := strconv.Atoi(params.MerchantNo)
			record.UserId = userId
			record.MerchantNo = XFMerchant.MerchantNo

			record.SerialNumber = utils.XF + globalMethod.GetNowTimeV2() + globalMethod.RandomString(10)
			record.WhOrderId = params.OutOrderNo

			yuanToFloat, _ := globalMethod.MoneyYuanToFloat(params.OrderPrice)
			record.WhAmount = yuanToFloat
			record.WhAccountNo = params.AccountNo
			record.WhAccountName = params.AccountName
			record.WhUserType = params.UserType
			record.WhIssuer = params.Issuer
			record.WhBankNo = params.BankNo

			record.NoticeUrl = interface_config.XF_PAY_NOTICE_URL + record.WhOrderId
			record.ApiNoticeUrl = params.ApiNotifyUrl
			record.Item = params.Item
			record.RecordClass = utils.A
			record.CreateTime = params.TradeTime
			record.EditTime = params.TradeTime
			record.Status = utils.I

			// 多通道代付
			switch XFMerchant.ChannelType {
			case utils.XF:
				//先锋
				record.RecordType = utils.XF

				outs, flag := apiXFPay(userId, yuanToFloat, record, XFMerchant)
				if !flag {
					out = outs
				} else {
					out["resultCode"] = "0000"
					out["msg"] = "请求成功"
					out["orderStatus"] = "WAITING_PAYMENT"
				}
			}
		}
	}

	the.Data["json"] = out
	the.ServeJSON()
	the.StopRun()
}

// 对接代付查询
// @router /api/query_pay/?:params [post]
func (the *ApiPay) ApiRechargePay() {
	params := models.ApiQueryParams{}
	params.MerchantNo = the.GetString("MerchantNo")
	params.OutTradeNo = the.GetString("OutTradeNo")
	params.Sign = the.GetString("Sign")

	//获取客户端ip
	ip := the.Ctx.Input.IP()

	// 校验参数签名
	check, out := apiRPImpl.CheckPayQueryParams(params, ip)
	if check {

		record := payMdl.SelectOneWithdrawRecordByOrderId(params.OutTradeNo)
		id, _ := strconv.Atoi(params.MerchantNo)
		info, _ := userMdl.SelectOneUserById(id)

		response := models.ApiQueryResponseBody{}
		response.OutTradeNo = record.WhOrderId
		response.OrderStatus = utils.GetApiOrderStatus()[record.Status]
		response.TradeNo = record.SerialNumber
		response.CompleteTime = record.EditTime

		response.Amount = globalMethod.MoneyYuanToString(record.WhAmount + info.PayFee)
		response.AmountNotFee = globalMethod.MoneyYuanToString(record.WhAmount)
		response.AmountFee = globalMethod.MoneyYuanToString(info.PayFee)

		sign := apiRPImpl.GenerateSignV2(response, info.ApiKey)
		response.Sign = sign

		out["resultCode"] = "0000"
		out["msg"] = record.Remark
		out["data"] = response
	}

	the.Data["json"] = out
	the.ServeJSON()
	the.StopRun()
}

// 对接代付余额查询
// @router /api/query_pay_balance/?:params [post]
func (the *ApiPay) ApiRechargePayBalance() {
	params := models.ApiQueryBalanceParams{}
	params.MerchantNo = the.GetString("MerchantNo")
	params.Timestamp = the.GetString("Timestamp")
	params.Sign = the.GetString("Sign")

	//获取客户端ip
	ip := the.Ctx.Input.IP()

	// 校验参数签名
	check, out := apiRPImpl.CheckPayQueryBalanceParams(params, ip)
	if check {

		id, _ := strconv.Atoi(params.MerchantNo)
		info, _ := userMdl.SelectOneUserById(id)

		response := models.ApiQueryBalanceResponseBody{}
		response.MerchantNo = strconv.Itoa(info.Id)
		response.TAmount = globalMethod.MoneyYuanToString(info.TotalAmount)
		response.UAmount = globalMethod.MoneyYuanToString(info.UsableAmount)
		response.FAmount = globalMethod.MoneyYuanToString(info.FrozenAmount)

		sign := apiRPImpl.GenerateSignV2(response, info.ApiKey)
		response.Sign = sign

		out["resultCode"] = "0000"
		out["msg"] = "查询成功"
		out["data"] = response
	}

	the.Data["json"] = out
	the.ServeJSON()
	the.StopRun()
}

// 先锋代付
func apiXFPay(userId int, yuanToFloat float64, record models.WithdrawRecord, merchant models.Merchant) (map[string]interface{}, bool) {
	out := make(map[string]interface{})

	//判断可用余额,冻结提现金额
	enough, rMsg := userMdl.SelectOneUserUsableAmount(userId, yuanToFloat, record)
	if !enough {
		out["resultCode"] = "9998"
		out["msg"] = rMsg
		return out, false
	}

	// 4.0.0版本
	//result, err := xfPay(record, merchant.SecretKey)

	// 5.0.0版本
	encode := encrypt.EncodeMd5([]byte(globalMethod.RandomString(32)))
	result, err := xfPayV2(record, encode, merchant.SecretKey)
	if err != nil {
		out["resultCode"] = "9998"
		out["msg"] = err
		return out, false
	}

	resp := models.XFPayResponseBody{}
	err = json.Unmarshal(result, &resp)
	if err != nil {
		sys.LogError("response data format is error:", err)
		out["resultCode"] = "9998"
		out["msg"] = "先锋代付响应数据格式错误"
		return out, false
	}

	if strings.Compare("00000", resp.ResCode) == 0 ||
		strings.Compare("00001", resp.ResCode) == 0 ||
		strings.Compare("00002", resp.ResCode) == 0 {
		return out, true
	} else {
		sys.LogDebug("先锋代付错误:", resp)
		out["resultCode"] = "9998"
		out["msg"] = "代付错误：" + resp.ResMessage
		return out, false
	}
}
